/*
 * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jeequan.jeepay.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayMemberDO;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.service.mapper.PayMemberMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2020-06-13
 */
@Service
public class PayMemberService extends ServiceImpl<PayMemberMapper, PayMemberDO> {

    @Autowired
    private PayMemberMapper payMemberMapper;

//    @Autowired private SysUserAuthService sysUserAuthService;
//    @Autowired private SysUserRoleRelaService sysUserRoleRelaService;

    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    /** 添加系统用户 **/
    @Transactional
    public void addSysUser(PayMemberDO payMemberDO, String sysType){

        //判断获取到选择的角色集合
//        String roleIdListStr = sysUser.extv().getString("roleIdListStr");
//        if(StringKit.isEmpty(roleIdListStr)) throw new BizException("请选择角色信息！");
//
//        List<String> roleIdList = JSONArray.parseArray(roleIdListStr, String.class);
//        if(roleIdList.isEmpty()) throw new BizException("请选择角色信息！");

        // 1.参数校验
        // 1.1.判断用户名
        if( StringUtils.isEmpty(payMemberDO.getUserName()) ) {
            throw new BizException("登录用户名不能为空！");
        }
        // 1.2.判断用户类型
        if( StringUtils.isEmpty(sysType) ) {
            throw new BizException("判断用户类型不能为空！");
        }

        // 1.3.登录用户名不可重复
        if( count(PayMemberDO.gw().eq(PayMemberDO::getSystemType, sysType).eq(PayMemberDO::getUserName, payMemberDO.getUserName())) > 0 ){
            throw new BizException("登录用户名已存在！");
        }

        // 2.设置用户类型
        payMemberDO.setSystemType(sysType); // 系统类型
        // 3.设置密码
        String authPwd = CS.DEFAULT_PWD;
        String salt = StringKit.getUUID(6); //6位随机数
        String userPwd = passwordEncoder.encode(String.format("%s:%s", authPwd, salt));
        payMemberDO.setPassword(userPwd);
        payMemberDO.setPayPassword(userPwd);
        this.save(payMemberDO);

        // 4.添加用户角色信息
        //saveUserRole(sysUser.getSysUserId(), new ArrayList<>());

    }

    //修改用户信息
    @Transactional
    public void updateSysUser(PayMemberDO payMemberDO){

        Long userId = payMemberDO.getId();
        PayMemberDO dbRecord = getById(userId);

        if (dbRecord == null) {
            throw new BizException("该用户不存在");
        }

        //修改了手机号， 需要修改auth表信息
        if(!dbRecord.getUserName().equals(payMemberDO.getUserName())){

            if(count(PayMemberDO.gw().eq(PayMemberDO::getSystemType, dbRecord.getSystemType()).eq(PayMemberDO::getUserName, payMemberDO.getUserName())) > 0){
                throw new BizException("该登录用户名已关联其他用户！");
            }
            //更改密码
            if(StringUtils.isNotEmpty(payMemberDO.getPassword())){
                String userPwd = passwordEncoder.encode(String.format("%s:%s", payMemberDO.getPassword(), dbRecord.getSalt()));
                payMemberDO.setPassword(userPwd);
            }
            //更改支付密码
            if(StringUtils.isNotEmpty(payMemberDO.getPayPassword())){
                String userPwd = passwordEncoder.encode(String.format("%s:%s", payMemberDO.getPayPassword(), dbRecord.getSalt()));
                payMemberDO.setPayPassword(userPwd);
            }
        }

        //修改用户主表
        baseMapper.updateById(payMemberDO);
    }


    /** 分配用户角色 **/
    @Transactional
    public void saveUserRole(Long userId, Integer roleId) {
        PayMemberDO sysUser = getById(userId);
        sysUser.setRoleId(roleId);
        //修改用户主表
        baseMapper.updateById(sysUser);
//        //删除用户之前的 角色信息
//        sysUserRoleRelaService.remove(SysUserRoleRela.gw().eq(SysUserRoleRela::getUserId, userId));
//        for (String roleId : roleIdList) {
//            SysUserRoleRela addRecord = new SysUserRoleRela();
//            addRecord.setUserId(userId); addRecord.setRoleId(roleId);
//            sysUserRoleRelaService.save(addRecord);
//        }
    }

    /** 删除用户 **/
    @Transactional
    public void removeUser(PayMemberDO sysUser, String sysType) {
        // 1.删除用户信息
        removeById(sysUser.getId());
    }


    /** 获取到商户的超管用户ID  **/
    public Integer findMchAdminUserId(String userId){
        PayMemberDO payMemberDO = getById(userId);
        return payMemberDO.getParentId();

    }

    public PayMemberDO selectByLogin(String loginUsernameStr, String mgr) {
        return getOne(PayMemberDO.gw().eq(PayMemberDO::getUserName, loginUsernameStr).eq(PayMemberDO::getSystemType, mgr));
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    public PayMemberDO queryById(Integer id){
        return payMemberMapper.selectById(id);
    }

    /**
     * 分页查询
     *
     * @param payMember 筛选条件
     * @param current 当前页码
     * @param size  每页大小
     * @return
     */
    public Page<PayMemberDO> paginQuery(PayMemberDO payMember, long current, long size){
        //1. 构建动态查询条件
        LambdaQueryWrapper<PayMemberDO> queryWrapper = new LambdaQueryWrapper<>();
        if(StrUtil.isNotBlank(payMember.getSystemType())){
            queryWrapper.eq(PayMemberDO::getSystemType, payMember.getSystemType());
        }
        if(StrUtil.isNotBlank(payMember.getUserName())){
            queryWrapper.eq(PayMemberDO::getUserName, payMember.getUserName());
        }
        if(StrUtil.isNotBlank(payMember.getSalt())){
            queryWrapper.eq(PayMemberDO::getSalt, payMember.getSalt());
        }
        if(StrUtil.isNotBlank(payMember.getPassword())){
            queryWrapper.eq(PayMemberDO::getPassword, payMember.getPassword());
        }
        if(StrUtil.isNotBlank(payMember.getPayPassword())){
            queryWrapper.eq(PayMemberDO::getPayPassword, payMember.getPayPassword());
        }
        if(StrUtil.isNotBlank(payMember.getApiKey())){
            queryWrapper.eq(PayMemberDO::getApiKey, payMember.getApiKey());
        }
        if(StrUtil.isNotBlank(payMember.getGoogleSecretKey())){
            queryWrapper.eq(PayMemberDO::getGoogleSecretKey, payMember.getGoogleSecretKey());
        }
        if(StrUtil.isNotBlank(payMember.getDfDomain())){
            queryWrapper.eq(PayMemberDO::getDfDomain, payMember.getDfDomain());
        }
        if(StrUtil.isNotBlank(payMember.getDfIp())){
            queryWrapper.eq(PayMemberDO::getDfIp, payMember.getDfIp());
        }
        if(StrUtil.isNotBlank(payMember.getPathId())){
            queryWrapper.eq(PayMemberDO::getPathId, payMember.getPathId());
        }
        if(StrUtil.isNotBlank(payMember.getRemark())){
            queryWrapper.eq(PayMemberDO::getRemark, payMember.getRemark());
        }
        if(StrUtil.isNotBlank(payMember.getSessionRandom())){
            queryWrapper.eq(PayMemberDO::getSessionRandom, payMember.getSessionRandom());
        }
        if(StrUtil.isNotBlank(payMember.getRealName())){
            queryWrapper.eq(PayMemberDO::getRealName, payMember.getRealName());
        }
        if(StrUtil.isNotBlank(payMember.getMobile())){
            queryWrapper.eq(PayMemberDO::getMobile, payMember.getMobile());
        }
        if(StrUtil.isNotBlank(payMember.getLoginIp())){
            queryWrapper.eq(PayMemberDO::getLoginIp, payMember.getLoginIp());
        }
        //2. 执行分页查询
        Page<PayMemberDO> pagin = new Page<>(current , size , true);
        IPage<PayMemberDO> selectResult = payMemberMapper.selectByPage(pagin , queryWrapper);
        pagin.setPages(selectResult.getPages());
        pagin.setTotal(selectResult.getTotal());
        pagin.setRecords(selectResult.getRecords());
        //3. 返回结果
        return pagin;
    }

    /**
     * 新增数据
     *
     * @param payMember 实例对象
     * @return 实例对象
     */
    public PayMemberDO insert(PayMemberDO payMember){
        payMemberMapper.insert(payMember);
        return payMember;
    }

    /**
     * 更新数据
     *
     * @param payMember 实例对象
     * @return 实例对象
     */
    public PayMemberDO update(PayMemberDO payMember){
        //1. 根据条件动态更新
        LambdaUpdateChainWrapper<PayMemberDO> chainWrapper = new LambdaUpdateChainWrapper<PayMemberDO>(payMemberMapper);
        if(StrUtil.isNotBlank(payMember.getSystemType())){
            chainWrapper.set(PayMemberDO::getSystemType, payMember.getSystemType());
        }
        if(StrUtil.isNotBlank(payMember.getUserName())){
            chainWrapper.set(PayMemberDO::getUserName, payMember.getUserName());
        }
        if(StrUtil.isNotBlank(payMember.getSalt())){
            chainWrapper.set(PayMemberDO::getSalt, payMember.getSalt());
        }
        if(StrUtil.isNotBlank(payMember.getPassword())){
            chainWrapper.set(PayMemberDO::getPassword, payMember.getPassword());
        }
        if(StrUtil.isNotBlank(payMember.getPayPassword())){
            chainWrapper.set(PayMemberDO::getPayPassword, payMember.getPayPassword());
        }
        if(StrUtil.isNotBlank(payMember.getApiKey())){
            chainWrapper.set(PayMemberDO::getApiKey, payMember.getApiKey());
        }
        if(StrUtil.isNotBlank(payMember.getGoogleSecretKey())){
            chainWrapper.set(PayMemberDO::getGoogleSecretKey, payMember.getGoogleSecretKey());
        }
        if(StrUtil.isNotBlank(payMember.getDfDomain())){
            chainWrapper.set(PayMemberDO::getDfDomain, payMember.getDfDomain());
        }
        if(StrUtil.isNotBlank(payMember.getDfIp())){
            chainWrapper.set(PayMemberDO::getDfIp, payMember.getDfIp());
        }
        if(StrUtil.isNotBlank(payMember.getPathId())){
            chainWrapper.set(PayMemberDO::getPathId, payMember.getPathId());
        }
        if(StrUtil.isNotBlank(payMember.getRemark())){
            chainWrapper.set(PayMemberDO::getRemark, payMember.getRemark());
        }
        if(StrUtil.isNotBlank(payMember.getSessionRandom())){
            chainWrapper.set(PayMemberDO::getSessionRandom, payMember.getSessionRandom());
        }
        if(StrUtil.isNotBlank(payMember.getRealName())){
            chainWrapper.set(PayMemberDO::getRealName, payMember.getRealName());
        }
        if(StrUtil.isNotBlank(payMember.getMobile())){
            chainWrapper.set(PayMemberDO::getMobile, payMember.getMobile());
        }
        if(StrUtil.isNotBlank(payMember.getLoginIp())){
            chainWrapper.set(PayMemberDO::getLoginIp, payMember.getLoginIp());
        }
        //2. 设置主键，并更新
        chainWrapper.eq(PayMemberDO::getId, payMember.getId());
        boolean ret = chainWrapper.update();
        //3. 更新成功了，查询最最对象返回
        if(ret){
            return queryById(payMember.getId().intValue());
        }else{
            return payMember;
        }
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    public boolean deleteById(Integer id){
        int total = payMemberMapper.deleteById(id);
        return total > 0;
    }
}
